package com.atguigu.gulimall.product;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.web.bind.annotation.ControllerAdvice;

/**
 * @author AyomGaming
 * 1.整合MyBatis-Plus
 *      1).导入依赖 mybatis-plus-boot-starter
 *      2).配置
 *          1.配置数据源
 *              1).导入数据库驱动
 *              2).在application.yml中配置数据源相关信息
 *          2.配置MyBatis-Plus
 *              1).使用@MapperScan配置扫描包
 *              2).告诉MyBatis-plus,sql映射文件位置
 * 2.逻辑删除
 *      1).配置全局的逻辑删除规则(高省略)
 *      2).配置逻辑删除的组件Bean(3.1.1开始不再需要:省略)
 *      3).给实体类字段加上逻辑删除注解     @TableLogic
 *
 * 3.JSR303
 *      1).给Bean添加校验注解  javax.validation.constraints,并定义自己的message提示
 *      2).开启校验功能@Valid
 *          效果:校验错误以后会有默认的响应
 *      3).给校验的Bean后紧跟一个BindingResult,就可以获取到校验的结果
 *      4).分组校验(多场景的复杂校验)
 *          1.给校验注解上标注什么情况需要进行校验
 *          2.在Controller类中操作的方法上 @Validated({分组接口.class})
 *          3.默认没有指定分组的校验注解,在分组校验的情况Validated({分组接口.class})下不生效,只会在@Validated生效
 * 4.统一的异常处理
 *      1).编写异常处理类,使用@ControllerAdvice
 *      2).使用 @ExceptionHandler 标注方法可以处理的异常
 * 5.自定义校验
 *      1).编写一个自定义的校验注解
 *      2).编写一个自定义的校验器
 *      3).关联自定义的校验器和自定义校验注解
 *      @Documented
 *      @Constraint(
 *         validatedBy = {ListValueConstraintValidator.class[可以指定多个不同的校验器,适配不同类型的校验]}
 *      )
 *      @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
 *      @Retention(RetentionPolicy.RUNTIME)
 *
 *      @EnableFeignClients(basePackages = "com.atguigu.gulimall.product.feign")     远程调用接口所在的包
 *      @EnableDiscoveryClient       注册中心
 *      @MapperScan("com.atguigu.gulimall.product.dao")  Mapper文件所在的包
 *      @SpringBootApplication       SpringBoot主程序类
 * 6.模板引擎
 *      1).thymeleaf-starter:开发期间关闭缓存,可以实时查看数据
 *      2).静态资源都放在static文件夹下就可以按照路径直接访问
 *      3).页面放在templates下,直接访问
 *          SpringBoot,访问项目的时候,默认会找index
 *      4).页面修改不重启服务器实时更新(前提是关闭thymeleaf缓存)
 *          1.引入dev-tools
 *          2.使用快捷键 Ctrl+F9或Ctrl+Shift+F9,代码配置推荐还是要重启服务!
 * 7.整合Redis
 *      1).引入spring-boot-starter-data-redis
 *      2).简单配置redis host等信息
 *      3).使用SpringBoot自动配置好的StringRedisTemplate来操作Redis
 *          redis  -->  Map 存放数据Key 数据值Value
 * 8.整合redisson作为分布式锁/分布式对象等功能框架
 *      1).引入依赖,Spring版
 *              <dependency>
 *             <groupId>org.redisson</groupId>
 *             <artifactId>redisson</artifactId>
 *             <version>3.12.5</version>
 *              </dependency>
 *      2).配置redisson   https://github.com/redisson/redisson/wiki/2.-配置方法
 *
 * 9.整合SpringCache简化缓存开发
 *      1).引入依赖     spring-boot-starter-cache,spring-boot-starter-data-redis
 *      2).配置
 *          1.自动配置
 *              CacheAutoConfiguration会导入   RedisCacheConfiguration
 *              自动配置了缓存管理器RedisCacheManager
 *          2.配置使用redis作为缓存
 *              spring.cache.type=redis
 *      3).测试使用缓存
 *          @Cacheable：触发​​缓存填充。
 *          @CacheEvict：触发​​缓存逐出。
 *          @CachePut：更新缓存，而不会干扰方法的执行。
 *          @Caching：重新组合要应用于一个方法的多个缓存操作。
 *          @CacheConfig：在类级别共享一些与缓存相关的常见设置。
 *          1.开启缓存功能        @EnableCaching
 *          2.只需要使用注解就能完成缓存操作
 *      4).原理
 *       CacheAutoConfiguration -->  RedisCacheConfiguration -->  RedisCacheManager
 *          -->初始化所有的缓存initialCacheNames(),每个缓存决定使用什么配置
 *              -->如果RedisCacheConfiguration有就用已有的,没有就用默认配置
 *                  -->想改缓存的配置,只需要给容器中放一个RedisCacheConfiguration即可
 *                      -->就会应用到当前缓存RedisCacheManager管理的所有缓存分区中
 *                          -->
 */
@EnableFeignClients(basePackages = "com.atguigu.gulimall.product.feign")
@EnableDiscoveryClient
@MapperScan("com.atguigu.gulimall.product.dao")
@EnableRedisHttpSession
@SpringBootApplication
public class GulimailProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimailProductApplication.class, args);
    }

}
